﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using AutoMapper;
using Core;
using IglooCoder.Commons.WcfNhibernate;
using Infrastucture;
using WcfService1.DTO;
using Omu.ValueInjecter;

namespace WcfService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "ItemServices" in code, svc and config file together.


    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [NHibernateContext]
    public class ItemServices : IItemServices
    {
        private readonly ItemRepository _itemRepository;
        private WcfSessionStorage _session;
        public ItemServices()
        {
            _session = new WcfSessionStorage();
            _itemRepository = new ItemRepository(_session);
        }

        #region IItemServices Members

        public List<ItemDTO> GetList(int page, out long recordCount, string sortProperty = null, string sortType = "ASC")
        {
            var Items = new List<Item>();
            var Results = new List<ItemDTO>();

            if (string.IsNullOrEmpty(sortProperty))
            {
                Items = _itemRepository.GetDataPaged(page, 30).ToList();
            }
            else
            {
                Items = _itemRepository.GetDataPaged(page, 30, sortProperty, sortType).ToList();
            }
            recordCount = _itemRepository.RecordCount;
            Items.ForEach(x =>
                              {
                                  var itemDto = new ItemDTO();
                                  itemDto.InjectFrom(x);
                                  if (x.SubGroup != null)
                                  {
                                      itemDto.SubGroup = new SubGroupDTO();
                                      itemDto.SubGroup.InjectFrom(x.SubGroup);
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaExpense))
                                  {
                                      itemDto.CoaExpense = new CoaDTO();
                                      itemDto.CoaExpense.AccountNumber = x.CoaExpense;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaHpp))
                                  {
                                      itemDto.CoaHpp = new CoaDTO();
                                      itemDto.CoaHpp.AccountNumber = x.CoaHpp;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaInventory))
                                  {
                                      itemDto.CoaInventory = new CoaDTO();
                                      itemDto.CoaInventory.AccountNumber = x.CoaInventory;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaSales))
                                  {
                                      itemDto.CoaSales = new CoaDTO();
                                      itemDto.CoaSales.AccountNumber = x.CoaSales;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaSalesReturn))
                                  {
                                      itemDto.CoaSalesReturn = new CoaDTO();
                                      itemDto.CoaSalesReturn.AccountNumber = x.CoaSalesReturn;
                                  }

                                  if (x.Satuan != null)
                                  {
                                      itemDto.Satuan = new SatuanDTO();
                                      itemDto.Satuan.InjectFrom(x.Satuan);
                                  }

                                  if (x.SatuanPack != null)
                                  {
                                      itemDto.SatuanPack = new SatuanDTO();
                                      itemDto.SatuanPack.InjectFrom(x.SatuanPack);
                                  }

                                  Results.Add(itemDto);
                              });
            return Results;
        }

        public bool Save(ItemDTO itemDto)
        {
            bool res;
            try
            {
                _itemRepository.ExecuteTransactionNative(()=>
                                                             {
                                                                 Item Item = _itemRepository.GetDataOne(x => x.ItemId == itemDto.ItemId);
                                                                 var user = new User();
                                                                 if (Item == null)
                                                                 {
                                                                     Item = new Item();
                                                                     itemDto.created_date = DateTime.Now;
                                                                 }
                                                                 else
                                                                 {
                                                                     itemDto.modified_date = DateTime.Now;
                                                                 }
                                                                 Mapper.Map(itemDto, Item);
                                                                 if (itemDto.CoaExpense != null)
                                                                    Item.CoaExpense = itemDto.CoaExpense.AccountNumber;
                                                                 if (itemDto.CoaHpp != null)
                                                                     Item.CoaHpp = itemDto.CoaHpp.AccountNumber;
                                                                 if (itemDto.CoaInventory != null)
                                                                    Item.CoaInventory = itemDto.CoaInventory.AccountNumber;
                                                                 if (itemDto.CoaSales != null)
                                                                    Item.CoaSales = itemDto.CoaSales.AccountNumber;
                                                                 if (itemDto.CoaSalesReturn != null)
                                                                    Item.CoaSalesReturn = itemDto.CoaSalesReturn.AccountNumber;
                                                                 _itemRepository.SaveOrUpdate(Item);
                                                             });
              
                res = true;
            }
            catch (Exception)
            {
                throw;
                res = false;
            }

            return res;
        }


        public bool Delete(ItemDTO itemDto,out string err)
        {
            bool res;
            err = string.Empty;
            try
            {
                var item = new Item();
                Mapper.Map(itemDto, item);
                InventoryRepository inventoryRepository = new InventoryRepository(_session);
                var inventories = inventoryRepository.GetDataList(x => x.Item.ItemId == item.ItemId);
                if (inventories.Count >= 1) throw new Exception("Item tidak boleh dihapus karena sudah link ke transaksi!");
                _itemRepository.Delete(item);
                res = true;
            }
            catch (Exception ex)
            {
                err = ex.Message;
                res = false;
            }

            return res;
        }


        public List<ItemDTO> GetListByCriteria(Dictionary<String, Object> criteria, string expression, int page,
                                               out long recordCount)
        {
            var items = new List<Item>();
            var Results = new List<ItemDTO>();
            items = _itemRepository.GetDataPaged(criteria, expression, page, 30).ToList();
            recordCount = _itemRepository.RecordCount;
            items.ForEach(x =>
                              {
                                  var itemDto = new ItemDTO();
                                  itemDto.InjectFrom(x);
                                  if (x.SubGroup != null)
                                  {
                                      itemDto.SubGroup = new SubGroupDTO();
                                      itemDto.SubGroup.InjectFrom(x.SubGroup);
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaExpense))
                                  {
                                      itemDto.CoaExpense = new CoaDTO();
                                      itemDto.CoaExpense.AccountNumber = x.CoaExpense;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaHpp))
                                  {
                                      itemDto.CoaHpp = new CoaDTO();
                                      itemDto.CoaHpp.AccountNumber = x.CoaHpp;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaInventory))
                                  {
                                      itemDto.CoaInventory = new CoaDTO();
                                      itemDto.CoaInventory.AccountNumber = x.CoaInventory;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaSales))
                                  {
                                      itemDto.CoaSales = new CoaDTO();
                                      itemDto.CoaSales.AccountNumber = x.CoaSales;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaSalesReturn))
                                  {
                                      itemDto.CoaSalesReturn = new CoaDTO();
                                      itemDto.CoaSalesReturn.AccountNumber = x.CoaSalesReturn;
                                  }

                                  if (x.Satuan != null)
                                  {
                                      itemDto.Satuan = new SatuanDTO();
                                      itemDto.Satuan.InjectFrom(x.Satuan);
                                  }

                                  if (x.SatuanPack != null)
                                  {
                                      itemDto.SatuanPack = new SatuanDTO();
                                      itemDto.SatuanPack.InjectFrom(x.SatuanPack);
                                  }
                                  Results.Add(itemDto);
                              });
            return Results;
        }


        public List<ItemDTO> GetItemByName(string ItemName)
        {
            var items = new List<Item>();
            var Results = new List<ItemDTO>();
            items = _itemRepository.GetDataList(x => x.ItemName.Contains(ItemName)).ToList();
            items.ForEach(x =>
                              {
                                  var itemDto = new ItemDTO();
                                  itemDto.InjectFrom(x);
                                  if (x.SubGroup != null)
                                  {
                                      itemDto.SubGroup = new SubGroupDTO();
                                      itemDto.SubGroup.InjectFrom(x.SubGroup);
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaExpense))
                                  {
                                      itemDto.CoaExpense = new CoaDTO();
                                      itemDto.CoaExpense.AccountNumber = x.CoaExpense;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaHpp))
                                  {
                                      itemDto.CoaHpp = new CoaDTO();
                                      itemDto.CoaHpp.AccountNumber = x.CoaHpp;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaInventory))
                                  {
                                      itemDto.CoaInventory = new CoaDTO();
                                      itemDto.CoaInventory.AccountNumber = x.CoaInventory;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaSales))
                                  {
                                      itemDto.CoaSales = new CoaDTO();
                                      itemDto.CoaSales.AccountNumber = x.CoaSales;
                                  }

                                  if (!string.IsNullOrEmpty(x.CoaSalesReturn))
                                  {
                                      itemDto.CoaSalesReturn = new CoaDTO();
                                      itemDto.CoaSalesReturn.AccountNumber = x.CoaSalesReturn;
                                  }

                                  if (x.Satuan != null)
                                  {
                                      itemDto.Satuan = new SatuanDTO();
                                      itemDto.Satuan.InjectFrom(x.Satuan);
                                  }

                                  if (x.SatuanPack != null)
                                  {
                                      itemDto.SatuanPack = new SatuanDTO();
                                      itemDto.SatuanPack.InjectFrom(x.SatuanPack);
                                  }

                                  Results.Add(itemDto);
                              });
            return Results;
        }

        public ItemDTO GetItem(string itemID)
        {
            Item item = _itemRepository.GetDataOne(x => x.ItemId == itemID);
            var itemDto = new ItemDTO();
            itemDto.InjectFrom(item);
            if (item.SubGroup != null)
            {
                itemDto.SubGroup = new SubGroupDTO();
                itemDto.SubGroup.InjectFrom(item.SubGroup);
            }

            if (!string.IsNullOrEmpty(item.CoaExpense))
            {
                itemDto.CoaExpense = new CoaDTO();
                itemDto.CoaExpense.AccountNumber = item.CoaExpense;
            }

            if (!string.IsNullOrEmpty(item.CoaHpp))
            {
                itemDto.CoaHpp = new CoaDTO();
                itemDto.CoaHpp.AccountNumber = item.CoaHpp;
            }

            if (!string.IsNullOrEmpty(item.CoaInventory))
            {
                itemDto.CoaInventory = new CoaDTO();
                itemDto.CoaInventory.AccountNumber = item.CoaInventory;
            }

            if (!string.IsNullOrEmpty(item.CoaSales))
            {
                itemDto.CoaSales = new CoaDTO();
                itemDto.CoaSales.AccountNumber = item.CoaSales;
            }

            if (!string.IsNullOrEmpty(item.CoaSalesReturn))
            {
                itemDto.CoaSalesReturn = new CoaDTO();
                itemDto.CoaSalesReturn.AccountNumber = item.CoaSalesReturn;
            }

            if (item.Satuan != null)
            {
                itemDto.Satuan = new SatuanDTO();
                itemDto.Satuan.InjectFrom(item.Satuan);
            }

            if (item.SatuanPack != null)
            {
                itemDto.SatuanPack = new SatuanDTO();
                itemDto.SatuanPack.InjectFrom(item.SatuanPack);
            }
            return itemDto;
        }

        public List<ItemDTO> GetAllItem()
        {
            var items = new List<Item>();
            items = _itemRepository.FetchAll().ToList();

            var results = new List<ItemDTO>();

            foreach (var item in items)
            {
                var itemDTO = new ItemDTO();
                itemDTO.InjectFrom(item);
                itemDTO.Satuan = new SatuanDTO();
                if (item.Satuan != null) itemDTO.Satuan.InjectFrom(item.Satuan);
                itemDTO.SatuanPack =new SatuanDTO();
                if (item.SatuanPack != null) itemDTO.SatuanPack.InjectFrom(item.SatuanPack);
                results.Add(itemDTO);
            }

            return results;
        }

        public bool SendEmail(ItemDTO itemDTO, String DestinationFolder)
        {
            var mailServices = new MailServices();
            var item = _itemRepository.GetDataOne(x => x.ItemId == itemDTO.ItemId);
            itemDTO = Mapper.Map(item, itemDTO);
            return mailServices.SendEmail(itemDTO,DestinationFolder);
        }

        #endregion
    }
}